package com.admin_system.service.impl;

import com.admin_system.entity.DocProcessResponse;
import com.admin_system.service.DocProcessService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.apache.http.client.config.RequestConfig;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;

@Service
@Slf4j
public class DocProcessServiceImpl implements DocProcessService {

    @Value("${python.docProcessService.url}")
    private String pythonServiceUrl;
    
    private final ObjectMapper objectMapper = new ObjectMapper();
    
    /**
     * 检查Python服务是否正常运行
     */
    @Override
    public boolean isServiceAvailable() {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet request = new HttpGet(pythonServiceUrl + "/health");
            try (CloseableHttpResponse response = httpClient.execute(request)) {
                return response.getStatusLine().getStatusCode() == 200;
            }
        } catch (Exception e) {
            log.error("检查Python服务状态失败", e);
            return false;
        }
    }
    
    /**
     * 发送文档到Python服务处理
     */
    @Override
    public DocProcessResponse processDocument(MultipartFile file) throws IOException {
        // 记录原始文件名，用于排查乱码问题
        log.info("处理文档，原始文件名: {}", file.getOriginalFilename());
        
        // 设置超时时间为10分钟（600000毫秒）
        RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(600000)
            .setSocketTimeout(600000)
            .build();
        try (CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build()) {
            HttpPost uploadFile = new HttpPost(pythonServiceUrl + "/process-document");
            
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.addBinaryBody(
                "file", 
                file.getInputStream(), 
                ContentType.APPLICATION_OCTET_STREAM, 
                file.getOriginalFilename()
            );
            
            HttpEntity multipart = builder.build();
            uploadFile.setEntity(multipart);
            
            try (CloseableHttpResponse response = httpClient.execute(uploadFile)) {
                HttpEntity responseEntity = response.getEntity();
                String responseBody = EntityUtils.toString(responseEntity);
                
                // 检查响应内容类型
                String contentType = response.getFirstHeader("Content-Type") != null ? 
                    response.getFirstHeader("Content-Type").getValue() : "";
                
                if (!contentType.contains("application/json")) {
                    log.error("Python服务返回了非JSON格式的响应: Content-Type={}, Response={}", contentType, responseBody);
                    DocProcessResponse errorResponse = new DocProcessResponse();
                    errorResponse.setError("服务器返回了无效的响应格式");
                    return errorResponse;
                }
                
                if (response.getStatusLine().getStatusCode() != 200) {
                    log.error("Python服务处理文档失败: Status={}, Response={}", 
                        response.getStatusLine().getStatusCode(), responseBody);
                    DocProcessResponse errorResponse = new DocProcessResponse();
                    errorResponse.setError("处理文档失败: " + responseBody);
                    return errorResponse;
                }
                
                try {
                    DocProcessResponse docResponse = objectMapper.readValue(responseBody, DocProcessResponse.class);
                    
                    // 验证响应数据的完整性
                    if (docResponse.getDownloadUrl() == null || docResponse.getFilename() == null) {
                        log.error("Python服务返回的响应数据不完整: {}", responseBody);
                        DocProcessResponse errorResponse = new DocProcessResponse();
                        errorResponse.setError("服务器返回的数据不完整");
                        return errorResponse;
                    }
                    
                    // 记录返回的文件名，用于排查乱码问题
                    log.info("Python服务返回的文件名: {}", docResponse.getFilename());
                    
                    return docResponse;
                } catch (Exception e) {
                    log.error("解析Python服务响应失败: {}", e.getMessage(), e);
                    DocProcessResponse errorResponse = new DocProcessResponse();
                    errorResponse.setError("解析服务器响应失败: " + e.getMessage());
                    return errorResponse;
                }
            }
        } catch (Exception e) {
            log.error("调用Python服务失败: {}", e.getMessage(), e);
            DocProcessResponse errorResponse = new DocProcessResponse();
            errorResponse.setError("调用处理服务失败: " + e.getMessage());
            return errorResponse;
        }
    }
    
    /**
     * 从Python服务下载处理后的文档
     */
    @Override
    public File downloadProcessedDocument(String downloadUrl) throws IOException {
        // 设置超时时间为10分钟（600000毫秒）
        RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(600000)
            .setSocketTimeout(600000)
            .build();
        try (CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build()) {
            // 直接使用URI创建HttpGet，避免特殊字符问题
            HttpGet request = new HttpGet(downloadUrl);
            
            try (CloseableHttpResponse response = httpClient.execute(request)) {
                if (response.getStatusLine().getStatusCode() != 200) {
                    throw new IOException("下载文件失败，状态码: " + response.getStatusLine().getStatusCode());
                }
                
                HttpEntity entity = response.getEntity();
                if (entity == null) {
                    throw new IOException("下载文件失败，响应为空");
                }
                
                // 创建临时文件
                Path tempFile = Files.createTempFile("processed-doc-", ".docx");
                
                // 保存响应内容到临时文件
                try (InputStream inputStream = entity.getContent()) {
                    Files.copy(inputStream, tempFile, StandardCopyOption.REPLACE_EXISTING);
                }
                
                return tempFile.toFile();
            }
        } catch (Exception e) {
            log.error("下载文件失败: {}", e.getMessage(), e);
            throw new IOException("下载文件失败: " + e.getMessage(), e);
        }
    }
} 